서울시 열린데이터 광장 데이터로 살펴본


# 파일을 불러와서 데이터프레임 생성
foreigner_num_origin = pd.read_csv('서울시 외국인 주민(국적별) 통계 2013-2018.csv'
,encoding='CP949', skiprows=1, thousands=',')
foreigner_num_origin
| 기간 | 구분 | 성별 | 합계 | 소계 | 중국 | 중국(한국계) | 대만 | 일본 | 몽골 | ... | 캐나다 | 소계.4 | 러시아 | 러시아(한국계) | 영국 | 기타.3 | 오세아니아 | 중남미 | 아프리카 | 기타.4 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2013 | 합계 | 계 | 395640.0 | 303856.0 | 51179.0 | 225201.0 | 9847.0 | 12482.0 | 5147.0 | ... | NaN | NaN | 2,088 | NaN | NaN | NaN | NaN | NaN | NaN | 24,783 |
| 1 | 2013 | 합계 | 남자 | 179261.0 | 134075.0 | 19632.0 | 102453.0 | 4989.0 | 4947.0 | 2054.0 | ... | NaN | NaN | 713 | NaN | NaN | NaN | NaN | NaN | NaN | 13,902 |
| 2 | 2013 | 합계 | 여자 | 216379.0 | 169781.0 | 31547.0 | 122748.0 | 4858.0 | 7535.0 | 3093.0 | ... | NaN | NaN | 1,375 | NaN | NaN | NaN | NaN | NaN | NaN | 10,881 |
| 3 | 2013 | 종로구 | 계 | 11880.0 | 7981.0 | 2584.0 | 4665.0 | 272.0 | 310.0 | 150.0 | ... | NaN | NaN | 62 | NaN | NaN | NaN | NaN | NaN | NaN | 1,005 |
| 4 | 2013 | 종로구 | 남자 | 5342.0 | 3286.0 | 1042.0 | 1952.0 | 125.0 | 118.0 | 49.0 | ... | NaN | NaN | 24 | NaN | NaN | NaN | NaN | NaN | NaN | 581 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 463 | 2018 | 강동구 | 계 | 6384.0 | 4570.0 | 652.0 | 3581.0 | 32.0 | 117.0 | 188.0 | ... | 159.0 | 76.0 | 29 | 8 | 18 | 21 | 77 | 17 | 17 | *** |
| 464 | 2018 | 강동구 | 남자 | 3034.0 | 2140.0 | 283.0 | 1761.0 | 12.0 | 11.0 | 73.0 | ... | 79.0 | 45.0 | 17 | *** | 13 | 12 | 45 | 10 | 9 | *** |
| 465 | 2018 | 강동구 | 여자 | 3350.0 | 2430.0 | 369.0 | 1820.0 | 20.0 | 106.0 | 115.0 | ... | 80.0 | 31.0 | 12 | 5 | 5 | 9 | 32 | 7 | 8 | *** |
| 466 | 2018 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
| 467 | 2018 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
468 rows × 44 columns
crime_most_five = pd.read_csv('서울시 5대 범죄 발생현황 2014-2018.csv'
,encoding='CP949', thousands=',')
crime_most_five
| 기간 | 자치구 | 합계 | 합계.1 | 살인 | 살인.1 | 강도 | 강도.1 | 강간강제추행 | 강간강제추행.1 | 절도 | 절도.1 | 폭력 | 폭력.1 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 기간 | 자치구 | 발생 | 검거 | 발생 | 검거 | 발생 | 검거 | 발생 | 검거 | 발생 | 검거 | 발생 | 검거 |
| 1 | 2018 | 합계 | 101,948 | 74,487 | 143 | 139 | 143 | 151 | 6,412 | 6,046 | 39,175 | 19,762 | 56,075 | 48,389 |
| 2 | 2018 | 종로구 | 3,690 | 3,913 | 6 | 7 | 3 | 7 | 236 | 1,100 | 1,483 | 969 | 1,962 | 1,830 |
| 3 | 2018 | 중구 | 4,030 | 2,679 | 2 | 2 | 11 | 11 | 207 | 115 | 1,855 | 832 | 1,955 | 1,719 |
| 4 | 2018 | 용산구 | 3,411 | 2,543 | 1 | 1 | 3 | 2 | 331 | 285 | 1,096 | 522 | 1,980 | 1,733 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 126 | 2014 | 관악구 | 6,781 | 3,701 | 7 | 8 | 25 | 22 | 361 | 238 | 3,029 | 784 | 3,359 | 2,649 |
| 127 | 2014 | 서초구 | 5,558 | 3,122 | 6 | 9 | 14 | 12 | 285 | 184 | 2,747 | 782 | 2,506 | 2,135 |
| 128 | 2014 | 강남구 | 8,851 | 5,262 | 13 | 9 | 37 | 29 | 512 | 403 | 3,895 | 1,193 | 4,394 | 3,628 |
| 129 | 2014 | 송파구 | 8,004 | 3,982 | 9 | 8 | 9 | 10 | 255 | 195 | 4,199 | 885 | 3,532 | 2,884 |
| 130 | 2014 | 강동구 | 5,392 | 3,285 | 5 | 4 | 10 | 8 | 148 | 129 | 2,425 | 827 | 2,804 | 2,317 |
131 rows × 14 columns
# 처음엔 이런 걸 그렸습니다
# 직관적이지 못함, 의미 파악이 어려움
fig = px.scatter_3d(result2.reset_index(), x='기간', y='중국국적총합', z='5대범죄_발생총합건수',
color='자치구', size_max=20, size='5대범죄_발생총합건수', width=800, height=800)
fig.show()
# Scattor plot의 모양새나, 연도별 변화를 봐도 두 변인 사이에 별 관계가 없어 보임
fig = px.scatter(result2.reset_index(), x='중국국적총합', y='5대범죄_발생총합건수',
color='자치구', size_max=15, size='5대범죄_발생총합건수', width=600, height=600
,animation_frame='기간')
fig.show()
fig = px.scatter(result2.reset_index(), x='중국국적총합', y='살인',
color='자치구', size_max=15, size='살인', width=600, height=600
,animation_frame='기간')
fig.show()
fig = px.scatter(result2.reset_index(), x='중국국적총합', y='강도',
color='자치구', size_max=15, size='강도', width=600, height=600
,animation_frame='기간')
fig.show()
fig = px.scatter(result2.reset_index(), x='중국국적총합', y='절도',
color='자치구', size_max=15, size='절도', width=600, height=600
,animation_frame='기간')
fig.show()
fig = px.scatter(result2.reset_index(), x='중국국적총합', y='강간강제추행',
color='자치구', size_max=15, size='강간강제추행', width=600, height=600
,animation_frame='기간')
fig.show()
fig = px.scatter(result2.reset_index(), x='중국국적총합', y='폭력',
color='자치구', size_max=15, size='폭력', width=600, height=600
,animation_frame='기간')
fig.show()
# 2018년 기준 각 요소들의 상관관계
for_corr2.corr(method='pearson')
| 중국국적총합 | 5대범죄_발생총합건수 | 살인 | 강도 | 강간강제추행 | 절도 | 폭력 | |
|---|---|---|---|---|---|---|---|
| 중국국적총합 | 1.000000 | 0.241903 | 0.557359 | 0.302846 | 0.118571 | 0.220225 | 0.260172 |
| 5대범죄_발생총합건수 | 0.241903 | 1.000000 | 0.594612 | 0.606587 | 0.801312 | 0.971584 | 0.974444 |
| 살인 | 0.557359 | 0.594612 | 1.000000 | 0.271016 | 0.469315 | 0.542147 | 0.607344 |
| 강도 | 0.302846 | 0.606587 | 0.271016 | 1.000000 | 0.496463 | 0.609513 | 0.569268 |
| 강간강제추행 | 0.118571 | 0.801312 | 0.469315 | 0.496463 | 1.000000 | 0.767011 | 0.717707 |
| 절도 | 0.220225 | 0.971584 | 0.542147 | 0.609513 | 0.767011 | 1.000000 | 0.902027 |
| 폭력 | 0.260172 | 0.974444 | 0.607344 | 0.569268 | 0.717707 | 0.902027 | 1.000000 |
# 영등포구를 제외한다면
for_corr.corr(method='pearson')
| 중국국적총합 | 5대범죄_발생총합건수 | 살인 | 강도 | 강간강제추행 | 절도 | 폭력 | |
|---|---|---|---|---|---|---|---|
| 중국국적총합 | 1.000000 | 0.063155 | 0.260940 | 0.268643 | -0.033064 | 0.044569 | 0.090311 |
| 5대범죄_발생총합건수 | 0.063155 | 1.000000 | 0.541375 | 0.595181 | 0.789114 | 0.968766 | 0.971732 |
| 살인 | 0.260940 | 0.541375 | 1.000000 | 0.227909 | 0.431302 | 0.478686 | 0.560923 |
| 강도 | 0.268643 | 0.595181 | 0.227909 | 1.000000 | 0.479638 | 0.597801 | 0.555354 |
| 강간강제추행 | -0.033064 | 0.789114 | 0.431302 | 0.479638 | 1.000000 | 0.751955 | 0.698744 |
| 절도 | 0.044569 | 0.968766 | 0.478686 | 0.597801 | 0.751955 | 1.000000 | 0.892135 |
| 폭력 | 0.090311 | 0.971732 | 0.560923 | 0.555354 | 0.698744 | 0.892135 | 1.000000 |
result = welfare_budget_from2014.merge(crime_most_five_end2017, how='left')
result
| 기간 | 자치구 | 금액(천원/명) | 상대격차(배) | 절대격차(천원/명) | 합계 | 살인 | 강도 | 강간강제추행 | 절도 | 폭력 | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2014 | 종로구 | 608.0 | 1.22 | 109.8 | 5021 | 3 | 12 | 226 | 2272 | 2508 |
| 1 | 2014 | 중구 | 702.8 | 1.41 | 204.7 | 5231 | 6 | 13 | 221 | 2576 | 2415 |
| 2 | 2014 | 용산구 | 486.6 | 0.98 | -11.5 | 3799 | 1 | 7 | 213 | 1560 | 2018 |
| 3 | 2014 | 성동구 | 495.6 | 0.99 | -2.6 | 3582 | 1 | 5 | 141 | 1753 | 1682 |
| 4 | 2014 | 광진구 | 414.9 | 0.83 | -83.2 | 6268 | 8 | 16 | 249 | 3167 | 2828 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 95 | 2017 | 관악구 | 621.7 | 0.93 | -44.4 | 5525 | 8 | 7 | 379 | 1979 | 3152 |
| 96 | 2017 | 서초구 | 487.8 | 0.73 | -178.3 | 4708 | 9 | 13 | 470 | 1812 | 2404 |
| 97 | 2017 | 강남구 | 537.6 | 0.81 | -128.4 | 7720 | 7 | 20 | 607 | 3130 | 3956 |
| 98 | 2017 | 송파구 | 481.2 | 0.72 | -184.8 | 5576 | 6 | 1 | 288 | 2274 | 3007 |
| 99 | 2017 | 강동구 | 666.6 | 1 | 0.6 | 4261 | 5 | 10 | 172 | 1645 | 2429 |
100 rows × 11 columns
fig = px.scatter(result, x='금액(천원/명)', y='합계',
color='자치구', size_max=15, size='합계', width=600, height=600
,animation_frame='기간')
fig.show()
for_corr = result[result['기간']==2017][['금액(천원/명)', '합계']]
for_corr
| 금액(천원/명) | 합계 | |
|---|---|---|
| 75 | 778.8 | 4057 |
| 76 | 905.0 | 4184 |
| 77 | 620.3 | 4060 |
| 78 | 620.7 | 2767 |
| 79 | 544.8 | 4646 |
| 80 | 754.6 | 3975 |
| 81 | 730.8 | 4571 |
| 82 | 695.6 | 3434 |
| 83 | 839.2 | 3393 |
| 84 | 716.9 | 1999 |
| 85 | 791.0 | 4209 |
| 86 | 761.7 | 3883 |
| 87 | 666.4 | 3113 |
| 88 | 668.8 | 5278 |
| 89 | 601.6 | 3882 |
| 90 | 716.9 | 5135 |
| 91 | 702.8 | 4895 |
| 92 | 870.1 | 3265 |
| 93 | 676.3 | 5969 |
| 94 | 632.3 | 3330 |
| 95 | 621.7 | 5525 |
| 96 | 487.8 | 4708 |
| 97 | 537.6 | 7720 |
| 98 | 481.2 | 5576 |
| 99 | 666.6 | 4261 |
# 0.4는 적어 보이지만, 사회과학에서는 유의미한 값으로 활용됨
for_corr.corr(method='pearson')
| 금액(천원/명) | 합계 | |
|---|---|---|
| 금액(천원/명) | 1.000000 | -0.406691 |
| 합계 | -0.406691 | 1.000000 |
subway = pd.read_csv('서울 자치구별 전철역 수 - Sheet1.csv', encoding='utf-8')
subway
| 자치구 | 전철역 수 | |
|---|---|---|
| 0 | 강남구 | 29 |
| 1 | 중구 | 23 |
| 2 | 송파구 | 22 |
| 3 | 마포구 | 22 |
| 4 | 강서구 | 21 |
| 5 | 영등포구 | 19 |
| 6 | 성동구 | 19 |
| 7 | 서초구 | 19 |
| 8 | 용산구 | 18 |
| 9 | 노원구 | 18 |
| 10 | 동작구 | 17 |
| 11 | 은평구 | 15 |
| 12 | 종로구 | 15 |
| 13 | 중랑구 | 14 |
| 14 | 구로구 | 13 |
| 15 | 강동구 | 11 |
| 16 | 동대문구 | 11 |
| 17 | 광진구 | 11 |
| 18 | 성북구 | 9 |
| 19 | 도봉구 | 7 |
| 20 | 서대문구 | 7 |
| 21 | 양천구 | 6 |
| 22 | 금천구 | 4 |
| 23 | 관악구 | 4 |
| 24 | 강북구 | 3 |
merged = crime_most_five[crime_most_five['기간'] == 2018].merge(subway, how='left').drop(columns='기간')
merged
| 자치구 | 합계 | 살인 | 강도 | 강간강제추행 | 절도 | 폭력 | 전철역 수 | |
|---|---|---|---|---|---|---|---|---|
| 0 | 종로구 | 3690 | 6 | 3 | 236 | 1483 | 1962 | 15 |
| 1 | 중구 | 4030 | 2 | 11 | 207 | 1855 | 1955 | 23 |
| 2 | 용산구 | 3411 | 1 | 3 | 331 | 1096 | 1980 | 18 |
| 3 | 성동구 | 2457 | 2 | 5 | 126 | 999 | 1325 | 19 |
| 4 | 광진구 | 3915 | 7 | 2 | 229 | 1769 | 1908 | 11 |
| 5 | 동대문구 | 3680 | 2 | 5 | 145 | 1447 | 2081 | 11 |
| 6 | 중랑구 | 4288 | 4 | 3 | 174 | 1526 | 2581 | 14 |
| 7 | 성북구 | 3042 | 7 | 1 | 183 | 1164 | 1687 | 9 |
| 8 | 강북구 | 3437 | 8 | 7 | 188 | 1112 | 2122 | 3 |
| 9 | 도봉구 | 2249 | 1 | 5 | 113 | 781 | 1349 | 7 |
| 10 | 노원구 | 4007 | 5 | 5 | 194 | 1422 | 2381 | 18 |
| 11 | 은평구 | 3590 | 8 | 1 | 188 | 1278 | 2115 | 15 |
| 12 | 서대문구 | 2802 | 5 | 3 | 206 | 1062 | 1526 | 7 |
| 13 | 마포구 | 5172 | 6 | 6 | 473 | 2011 | 2676 | 22 |
| 14 | 양천구 | 3515 | 2 | 4 | 120 | 1384 | 2005 | 6 |
| 15 | 강서구 | 4629 | 11 | 6 | 269 | 1724 | 2619 | 21 |
| 16 | 구로구 | 4810 | 8 | 9 | 250 | 1717 | 2826 | 13 |
| 17 | 금천구 | 3293 | 6 | 7 | 200 | 1168 | 1912 | 4 |
| 18 | 영등포구 | 5840 | 17 | 8 | 391 | 2292 | 3132 | 19 |
| 19 | 동작구 | 3100 | 3 | 7 | 288 | 1151 | 1651 | 17 |
| 20 | 관악구 | 5026 | 9 | 10 | 352 | 2012 | 2643 | 4 |
| 21 | 서초구 | 4726 | 5 | 5 | 470 | 1851 | 2395 | 19 |
| 22 | 강남구 | 7513 | 10 | 14 | 600 | 3004 | 3885 | 29 |
| 23 | 송파구 | 5807 | 5 | 6 | 309 | 2352 | 3135 | 22 |
| 24 | 강동구 | 3919 | 3 | 7 | 170 | 1515 | 2224 | 11 |
fig = px.scatter(merged
,x='전철역 수'
,y='절도'
,color='자치구'
,size_max=15
,size='절도'
,width=600, height=600)
fig.show()
fig = px.scatter(merged, x='전철역 수', y='폭력'
,color='자치구'
,size_max=15
,size='폭력'
,width=600, height=600)
fig.show()
fig = px.scatter(merged, x='전철역 수', y='강간강제추행'
,color='자치구'
,size_max=15
,size='강간강제추행'
,width=600, height=600)
fig.show()
fig = px.scatter(merged, x='전철역 수', y='강도'
,color='자치구'
,size_max=15
,size='강도'
,width=600, height=600)
fig.show()
fig = px.scatter(merged, x='전철역 수', y='살인'
,color='자치구'
,size_max=15
,size='살인'
,width=600, height=600)
fig.show()
merged.corr(method='pearson')
| 합계 | 살인 | 강도 | 강간강제추행 | 절도 | 폭력 | 전철역 수 | |
|---|---|---|---|---|---|---|---|
| 합계 | 1.000000 | 0.594612 | 0.606587 | 0.801312 | 0.971584 | 0.974444 | 0.580999 |
| 살인 | 0.594612 | 1.000000 | 0.271016 | 0.469315 | 0.542147 | 0.607344 | 0.140307 |
| 강도 | 0.606587 | 0.271016 | 1.000000 | 0.496463 | 0.609513 | 0.569268 | 0.318223 |
| 강간강제추행 | 0.801312 | 0.469315 | 0.496463 | 1.000000 | 0.767011 | 0.717707 | 0.592739 |
| 절도 | 0.971584 | 0.542147 | 0.609513 | 0.767011 | 1.000000 | 0.902027 | 0.599340 |
| 폭력 | 0.974444 | 0.607344 | 0.569268 | 0.717707 | 0.902027 | 1.000000 | 0.512349 |
| 전철역 수 | 0.580999 | 0.140307 | 0.318223 | 0.592739 | 0.599340 | 0.512349 | 1.000000 |
result = moved_num.merge(crime_most_five, how='left')
result
| 기간 | 자치구 | 이동한 인구 수 | 합계 | 살인 | 강도 | 강간강제추행 | 절도 | 폭력 | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | 2014 | 종로구 | 24191 | 5021 | 3 | 12 | 226 | 2272 | 2508 |
| 1 | 2014 | 중구 | 20105 | 5231 | 6 | 13 | 221 | 2576 | 2415 |
| 2 | 2014 | 용산구 | 35618 | 3799 | 1 | 7 | 213 | 1560 | 2018 |
| 3 | 2014 | 성동구 | 46521 | 3582 | 1 | 5 | 141 | 1753 | 1682 |
| 4 | 2014 | 광진구 | 56778 | 6268 | 8 | 16 | 249 | 3167 | 2828 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 120 | 2018 | 관악구 | 94403 | 5026 | 9 | 10 | 352 | 2012 | 2643 |
| 121 | 2018 | 서초구 | 74658 | 4726 | 5 | 5 | 470 | 1851 | 2395 |
| 122 | 2018 | 강남구 | 91611 | 7513 | 10 | 14 | 600 | 3004 | 3885 |
| 123 | 2018 | 송파구 | 101060 | 5807 | 5 | 6 | 309 | 2352 | 3135 |
| 124 | 2018 | 강동구 | 59334 | 3919 | 3 | 7 | 170 | 1515 | 2224 |
125 rows × 9 columns
for_corr3 = result[result['기간'] == 2018].loc[:, '이동한 인구 수':]
for_corr3.corr(method='pearson')
| 이동한 인구 수 | 합계 | 살인 | 강도 | 강간강제추행 | 절도 | 폭력 | |
|---|---|---|---|---|---|---|---|
| 이동한 인구 수 | 1.000000 | 0.626943 | 0.382918 | 0.244559 | 0.504526 | 0.594899 | 0.623106 |
| 합계 | 0.626943 | 1.000000 | 0.594612 | 0.606587 | 0.801312 | 0.971584 | 0.974444 |
| 살인 | 0.382918 | 0.594612 | 1.000000 | 0.271016 | 0.469315 | 0.542147 | 0.607344 |
| 강도 | 0.244559 | 0.606587 | 0.271016 | 1.000000 | 0.496463 | 0.609513 | 0.569268 |
| 강간강제추행 | 0.504526 | 0.801312 | 0.469315 | 0.496463 | 1.000000 | 0.767011 | 0.717707 |
| 절도 | 0.594899 | 0.971584 | 0.542147 | 0.609513 | 0.767011 | 1.000000 | 0.902027 |
| 폭력 | 0.623106 | 0.974444 | 0.607344 | 0.569268 | 0.717707 | 0.902027 | 1.000000 |

with open('시군구_위치데이터/seoul_municipalities_geo.json') as seoul_json:
data = json.load(seoul_json)
interact(create_seoul_crime_map,
crime_most_five=fixed(crime_most_five),
crime_name=['살인', '강도', '절도', '폭력', '강간강제추행'],
year=(2014, 2017, 1),
color=['darkred', 'darkblue', 'purple', 'green'])
<function __main__.create_seoul_crime_map(crime_most_five, crime_name, year, color)>
import statsmodels.api as sm
import statsmodels.formula.api as smf
# 다중선형회귀 적합
model = smf.ols(formula = '합계 ~ 인당복지예산 + 이사인구 + 지하철역수', data = for_modeling_rename)
result = model.fit()
result.summary()
| Dep. Variable: | 합계 | R-squared: | 0.517 |
|---|---|---|---|
| Model: | OLS | Adj. R-squared: | 0.502 |
| Method: | Least Squares | F-statistic: | 34.25 |
| Date: | Tue, 03 Dec 2019 | Prob (F-statistic): | 3.88e-15 |
| Time: | 19:05:32 | Log-Likelihood: | -820.92 |
| No. Observations: | 100 | AIC: | 1650. |
| Df Residuals: | 96 | BIC: | 1660. |
| Df Model: | 3 | ||
| Covariance Type: | nonrobust |
| coef | std err | t | P>|t| | [0.025 | 0.975] | |
|---|---|---|---|---|---|---|
| Intercept | 3435.0732 | 790.867 | 4.343 | 0.000 | 1865.214 | 5004.932 |
| 인당복지예산 | -1.8037 | 0.943 | -1.913 | 0.059 | -3.675 | 0.068 |
| 이사인구 | 0.0247 | 0.005 | 4.912 | 0.000 | 0.015 | 0.035 |
| 지하철역수 | 67.7401 | 14.117 | 4.798 | 0.000 | 39.717 | 95.763 |
| Omnibus: | 2.535 | Durbin-Watson: | 2.478 |
|---|---|---|---|
| Prob(Omnibus): | 0.282 | Jarque-Bera (JB): | 1.888 |
| Skew: | -0.161 | Prob(JB): | 0.389 |
| Kurtosis: | 2.409 | Cond. No. | 5.69e+05 |